package cn.bookcycle.panda.pay.util;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import cn.bookcycle.panda.pay.constant.BusinessData;
import cn.bookcycle.panda.pay.constant.SymbolData;

/**
 * 数据格式转化类
 * 
 * @author liufenglin
 * @date 2018年1月29日
 */
public class DataFormatConvert {
	/**日志*/
	private static final Logger logger = LoggerFactory.getLogger(DataFormatConvert.class);
	
	/**
	 * 把键值对形式的参数转化成为XML格式
	 * 
	 * @param map 以键值对形式保存的请求参数
	 * @return XML格式数据
	 */
	public static String mapToXML(Map<String, Object> map) {
		// 返回的XML数据
		String xml = null;
		// 用dom4j建立XML格式数据
		Document document = DocumentHelper.createDocument();
		// 添加XML的根节点
		Element root = document.addElement("xml");
		// 获取map的键的集合
		Set<String> keys = map.keySet();
		// 遍历由必须参数构成的map
		for (String key : keys) {
			// 添加XML的元素节点，并添加XML的元素节点对应的值
			root.addElement(key).addText(map.get(key).toString());
		}
		// 将XML转化为String
		String xmlStr = document.asXML();
		// 对生成的xml数据进行清洗，去掉xml注释
		int beginIndex = xmlStr.indexOf("?>");
		xmlStr = xmlStr.substring(beginIndex + 2).trim();
		return xmlStr;
	}
	
	
	/**
	 * 把xml格式的数据转化为json格式的数据
	 * 
	 * @param xml XML格式的数据，是String类型
	 * @return Json格式的数据，是String类型
	 */
	public static String xmlToJson(String xml) {
		logger.info("xmlToJson中的xml内容是： {}", xml);
		
		// 文档对象
		Document document = null;
		// json数组对象
		JSONArray jsonArray = null;
		// 最终返回的json串
		String jsonStr = null;
		if (xml != null) {
			try {
				// 创建解析xml字符串的文档对象，将字符串转为XML
				document = DocumentHelper.parseText(xml);
				// 获取根节点
				Element root = document.getRootElement();
				// 获取根节点的迭代器
				Iterator iterator = root.elementIterator();
				// 用Hashmap来存方节点名和对应的节点值
				Map<String, String> map = new HashMap<String, String>();
				// 遍历子节点
				while (iterator.hasNext()) {
					// 获取子节点，由于我们已经规定了json的格式，在子节点下面已经不存在子节点，因此不需要递归遍历
					Element subElement = (Element) iterator.next();
					// 获取子节点的名字和子节点的值存入map中
					map.put(subElement.getName(), subElement.getData().toString());
					logger.info("elementName:" + subElement.getName() + "	elementData:" + subElement.getData());

				}
				jsonArray = new JSONArray();
				// 把map转为json
				jsonArray.put(map);
				// 过滤掉 斜杠符号,这个斜杠是由于org,json不识别转义符号，多余产生的
				jsonStr = jsonArray.toString().replace(SymbolData.BACK_SLANT, "");
				int beginIndex = jsonStr.indexOf("{");
				int endIndex = jsonStr.lastIndexOf("}");
				// 去掉头尾多余的符号
				jsonStr = jsonStr.substring(beginIndex, endIndex + 1);
			} catch (DocumentException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		} else {
			logger.info("xmlToJson不对空的xml进行处理");
		}
		
		logger.info("XML格式转换后返回JSON串: {}", jsonStr);
		return jsonStr;
	}
	
	/**
	 * 把json格式的字符串转为Map
	 * 
	 * @param jsonStr json格式字符串
	 * @return Map<{@link String}, {@link String}>
	 */
	public static Map<String, String> jsonToMap(String jsonStr) {
		Map<String, String> map = new HashMap<String, String>();
		try {
			JSONObject jsonObject = new JSONObject(jsonStr);
			// 获取所有json数据的键值
			Iterator<String> it = jsonObject.keys();
			while (it.hasNext()) {
				// 获取键
				String key = it.next();
				// 获取值
				String value = jsonObject.getString(key);
				map.put(key, value);
			}
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return map;
	}
	
	/**
	 * 清洗JSON数据为标准格式的JSON
	 * 
	 * @param json
	 * @return
	 */
	public static String washJson(String json) {
		if (json != null) {
			int beginIndex = json.indexOf("{");
			int endIndex = json.lastIndexOf("}");
			json = json.substring(beginIndex, endIndex + 1);
		}
		return json;
	}
	
	/**
	 * 去掉map转String后产生的括号
	 * 
	 * @param mapStr
	 * @return
	 */
	public static String delBrackets(String mapStr) {
		int beginIndex = mapStr.indexOf(SymbolData.BRACKET);
		int endIndex = mapStr.indexOf(SymbolData.BACK_BRACKET);
		return mapStr.substring(beginIndex + 1, endIndex);
	}
}
